from flask import Flask, request, jsonify, render_template_string
import requests
import json
import os

app = Flask(__name__)

# 使用你提供的 Authorization token 和 App ID
beaver = 'Bearer bce-v3/ALTAK-X96iO5hyb2sN8KEhdiKoc/00e436f2edcb2733b26e19ef60f651c1aaa72fd3'
app_id = "94a09af2-a754-4ace-aca0-ba899fc477cb"

# 用于缓存 conversation_id
conversation_id_cache = None

# HTML 模板和样式，嵌入到 Python 文件中
html_template = """
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Chatbot Interface</title>
    <style>
        body {
            font-family: Arial, sans-serif;
            background-color: #f4f4f4;
            margin: 0;
            padding: 0;
        }
        .container {
            width: 80%;
            margin: 0 auto;
            padding: 20px;
            background-color: white;
            margin-top: 50px;
            box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);
        }
        h1 {
            text-align: center;
            color: #333;
        }
        .chat-box {
            background-color: #fafafa;
            border: 1px solid #ddd;
            padding: 10px;
            height: 300px;
            overflow-y: scroll;
            margin-bottom: 20px;
        }
        .user-message, .bot-message {
            margin: 10px 0;
            padding: 10px;
            border-radius: 5px;
        }
        .user-message {
            background-color: #d1ecf1;
            text-align: right;
        }
        .bot-message {
            background-color: #f8d7da;
            text-align: left;
        }
        .input-area {
            display: flex;
        }
        .input-area input[type="text"] {
            flex-grow: 1;
            padding: 10px;
            border: 1px solid #ddd;
            border-radius: 5px;
        }
        .input-area button {
            padding: 10px 20px;
            border: none;
            background-color: #007bff;
            color: white;
            cursor: pointer;
            border-radius: 5px;
            margin-left: 10px;
        }
        .input-area button:hover {
            background-color: #0056b3;
        }
        .file-upload {
            margin-top: 10px;
            display: flex;
            align-items: center;
        }
        .file-upload input {
            padding: 5px;
        }
        .file-upload button {
            margin-left: 10px;
            padding: 8px 15px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h1>Chat with Bot</h1>
        <div class="chat-box" id="chat-box">
            <!-- Chat messages will appear here -->
        </div>
        <div class="input-area">
            <input type="text" id="user-input" placeholder="Type your message here">
            <button onclick="sendMessage()">Send</button>
        </div>
        <div class="file-upload">
            <input type="file" id="file-input">
            <button onclick="uploadFile()">Upload Image</button>
        </div>
    </div>

    <script>
        let uploadedFileId = null;
        let conversationId = null;  // 用于缓存 conversation_id

        function sendMessage() {
            const userInput = document.getElementById("user-input").value;
            if (userInput === '') return;

            // Add user message to chat box
            const chatBox = document.getElementById("chat-box");
            const userMessage = document.createElement("div");
            userMessage.classList.add("user-message");
            userMessage.textContent = userInput;
            chatBox.appendChild(userMessage);

            // 修改发送请求的字段，增加 app_id 和 stream 字段
            fetch('/chat', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json'
                },
                body: JSON.stringify({
                    query: userInput,
                    file_ids: uploadedFileId ? [uploadedFileId] : [],
                    conversation_id: conversationId,  // 使用统一的 conversation_id
                    stream: false  // 添加 stream 字段
                })
            })
            .then(response => response.json())
            .then(data => {
                // Add bot message to chat box
                const botMessage = document.createElement("div");
                botMessage.classList.add("bot-message");
                botMessage.textContent = data.answer;
                chatBox.appendChild(botMessage);

                // Clear the input field
                document.getElementById("user-input").value = '';

                // Scroll to the bottom of the chat
                chatBox.scrollTop = chatBox.scrollHeight;
            });
        }

        function uploadFile() {
            const fileInput = document.getElementById('file-input');
            const file = fileInput.files[0];
            if (!file) return;

            const formData = new FormData();
            formData.append('file', file);

            // Upload file to server
            fetch('/upload', {
                method: 'POST',
                body: formData
            })
            .then(response => response.json())
            .then(data => {
                if (data.id && data.conversation_id) {
                    uploadedFileId = data.id;
                    conversationId = data.conversation_id;  // 缓存 conversation_id
                    alert('File uploaded successfully with ID: ' + data.id);
                } else {
                    alert('File upload failed.');
                }
            });
        }
    </script>
</body>
</html>
"""

# 上传文件到百度千帆，并返回 conversation_id 和 file_id
def upload_image_to_qianfan(file):
    url = "https://qianfan.baidubce.com/v2/app/conversation/file/upload"
    
    payload = {
        'app_id': app_id
    }
    files = [
        ('file', (file.filename, file.stream, file.mimetype))
    ]
    headers = {
        'X-Appbuilder-Authorization': beaver
    }

    # 发起文件上传请求
    print(f"Uploading file to {url} with headers: {headers} and payload: {payload} and files: {files}")
    response = requests.post(url, headers=headers, data=payload, files=files)
    
    # 打印上传文件的响应，便于调试
    print(f"File upload response: {response.status_code}, {response.text}")

    if response.status_code == 200:
        response_json = response.json()
        file_id = response_json.get("id")
        conversation_id = response_json.get("conversation_id")
        print(f"Uploaded file ID: {file_id}, Conversation ID: {conversation_id}")
        return file_id, conversation_id
    else:
        print(f"Failed to upload file: {response.text}")
        return None, None

# 跟百度千帆API交互的函数
def get_bot_response(user_input, file_id=None, conversation_id=None):
    url = "https://qianfan.baidubce.com/v2/app/conversation/runs"
    
    payload = {
        "app_id": app_id,  # 使用提供的 app_id
        "query": user_input,
        "stream": False,
        "conversation_id": conversation_id  # 使用缓存的 conversation_id
    }

    if file_id:
        payload["file_ids"] = [file_id]

    headers = {
        'Content-Type': 'application/json',
        'X-Appbuilder-Authorization': beaver  # 使用提供的 beaver
    }

    # 打印发送到百度千帆API的请求体
    print(f"Sending request to {url} with headers: {headers} and payload: {payload}")

    response = requests.post(url, headers=headers, json=payload)
    
    # 打印API的原始响应，便于调试
    print("Response Status Code:", response.status_code)
    print("Response JSON:", response.text)
    
    try:
        response_json = response.json()
    except json.JSONDecodeError:
        return "Error: Unable to decode the response from the server."

    # 提取 answer 字段，如果没有就返回默认信息
    return response_json.get("answer", "Sorry, I couldn't understand your message.")

# 首页路由，渲染前端页面
@app.route('/')
def index():
    return render_template_string(html_template, app_id=app_id)

# 处理聊天请求的路由
@app.route('/chat', methods=['POST'])
def chat():
    payload = request.json

    # 从 payload 中获取文件 ID 和 conversation_id
    file_id = payload.get('file_ids', [None])[0]
    conversation_id = payload.get('conversation_id')

    if not file_id or not conversation_id:
        print("Missing file ID or conversation ID")
        return jsonify({"error": "Missing file ID or conversation ID"}), 400

    # 打印接收到的请求体，便于调试
    print(f"Received chat request with payload: {json.dumps(payload, indent=4, ensure_ascii=False)}")

    # 覆盖使用服务器端的 app_id 和 stream
    payload['app_id'] = app_id
    payload['stream'] = False

    # 设置百度API的 URL 和 headers
    url = "https://qianfan.baidubce.com/v2/app/conversation/runs"
    headers = {
        'Content-Type': 'application/json',
        'X-Appbuilder-Authorization': beaver
    }

    # 打印将发送到百度API的请求体
    print(f"Sending request to Baidu API with payload: {json.dumps(payload, indent=4, ensure_ascii=False)}")

    # 发起请求
    response = requests.post(url, headers=headers, json=payload)

    # 打印百度API的响应体，便于调试
    print(f"Response from Baidu API: {response.status_code}, {response.text}")

    # 返回百度API的响应
    return jsonify(response.json()), response.status_code

# 处理图片上传请求的路由
@app.route('/upload', methods=['POST'])
def upload():
    if 'file' not in request.files:
        return jsonify({"error": "No file part"}), 400

    file = request.files['file']
    if file.filename == '':
        return jsonify({"error": "No selected file"}), 400

    # 打印收到的上传请求体
    print(f"Received upload request with file: {file.filename}")

    # 上传文件到百度千帆
    file_id, conversation_id = upload_image_to_qianfan(file)
    if file_id and conversation_id:
        return jsonify({"id": file_id, "conversation_id": conversation_id})
    else:
        return jsonify({"error": "Failed to upload file"}), 500

if __name__ == '__main__':
    app.run(debug=True)
